<template>
  <div class="edit-wrapper" :style="styles">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :default-config="toolbarConfig"
      :editor="editorRef"
      :mode="mode" />
    <Editor
      v-model="valueHtml"
      class="edit-box"
      :default-config="editorConfig"
      :mode="mode"
      @on-created="handleCreated"
    />
  </div>
</template>

<script lang="ts" setup>
import { computed, onBeforeUnmount, shallowRef } from "vue";
import xss from "xss";
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import type { IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
import { addUnit } from "@/utils/util";
import type { CSSProperties } from "vue";

const emit = defineEmits<{
  (event: "update:modelValue", value: string): void
}>();

const props = withDefaults(defineProps<{
  modelValue?: string
  mode?: "default" | "simple"
  height?: string | number
  width?: string | number
  toolbarConfig?: Partial<IToolbarConfig>
}>(), {
  modelValue: "",
  mode: "default", // simple
  height: "100%",
  width: "auto",
  toolbarConfig: () => ({})
});

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
const editorConfig: Partial<IEditorConfig> = {
  placeholder: "请输入内容..."
};


// 样式
const styles = computed<CSSProperties>(() => ({
  height: addUnit(props.height),
  width: addUnit(props.width)
}));

// 内容更新
const valueHtml = computed({
  get() {
    return props.modelValue;
  },
  set(value: string) {
    const safeHtml = xss(value);
    // console.log('处理过 xss 攻击的 html', safeHtml)
    emit("update:modelValue", safeHtml);
  }
});


// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const { value } = editorRef;
  if (value === null) return;
  value.destroy();
});
const handleCreated = (editor: any) => {
  editorRef.value = editor; // 记录 editor 实例，重要！
};
</script>

<style lang="less" scoped>
.edit-wrapper {
  display: flex;
  flex-direction: column;
  border: 1px solid #ccc;

  .edit-box {
    flex: 1;
    overflow-y: auto;
  }
}
</style>
